home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / perl / perl5a1.lha / perl5alpha1 / do / split < prev    next >
Encoding:
Text File  |  1992-08-15  |  5.6 KB  |  236 lines

  1. int
  2. do_split(TARG,spat,limit,gimme,arglast)
  3. STR *TARG;
  4. register SPAT *spat;
  5. register int limit;
  6. int gimme;
  7. int *arglast;
  8. {
  9.     register ARRAY *ary = stack;
  10.     STR **st = ary->ary_array;
  11.     register int sp = arglast[0] + 1;
  12.     register char *s = str_get(st[sp]);
  13.     char *strend = s + st[sp--]->str_cur;
  14.     register STR *dstr;
  15.     register char *m;
  16.     int iters = 0;
  17.     int maxiters = (strend - s) + 10;
  18.     int i;
  19.     char *orig;
  20.     int origlimit = limit;
  21.     int realarray = 0;
  22.  
  23.     if (!spat || !s)
  24.     fatal("panic: do_split");
  25.     else if (spat->spat_runtime) {
  26.     nointrp = "|)";
  27.     sp = eval(spat->spat_runtime,G_SCALAR,sp);
  28.     st = stack->ary_array;
  29.     m = str_get(dstr = st[sp--]);
  30.     nointrp = "";
  31.     if (*m == ' ' && dstr->str_cur == 1) {
  32.         str_set(dstr,"\\s+");
  33.         m = dstr->str_ptr;
  34.         spat->spat_flags |= SPAT_SKIPWHITE;
  35.     }
  36.     if (spat->spat_regexp) {
  37.         regfree(spat->spat_regexp);
  38.         spat->spat_regexp = Null(REGEXP*);    /* avoid possible double free */
  39.     }
  40.     spat->spat_regexp = regcomp(m,m+dstr->str_cur,
  41.         spat->spat_flags & SPAT_FOLD);
  42.     if (spat->spat_flags & SPAT_KEEP ||
  43.         (spat->spat_runtime->arg_type == O_ITEM &&
  44.           (spat->spat_runtime[1].arg_type & A_MASK) == A_SINGLE) ) {
  45.         arg_free(spat->spat_runtime);    /* it won't change, so */
  46.         spat->spat_runtime = Nullarg;    /* no point compiling again */
  47.     }
  48.     }
  49. #ifdef DEBUGGING
  50.     if (debug & 8) {
  51.     deb("2.SPAT /%s/\n",spat->spat_regexp->precomp);
  52.     }
  53. #endif
  54.     ary = stab_xarray(spat->spat_repl[1].arg_ptr.arg_stab);
  55.     if (ary && (gimme != G_ARRAY || (spat->spat_flags & SPAT_ONCE))) {
  56.     realarray = 1;
  57.     if (!(ary->ary_flags & ARF_REAL)) {
  58.         ary->ary_flags |= ARF_REAL;
  59.         for (i = ary->ary_fill; i >= 0; i--)
  60.         ary->ary_array[i] = Nullstr;    /* don't free mere refs */
  61.     }
  62.     ary->ary_fill = -1;
  63.     sp = -1;    /* temporarily switch stacks */
  64.     }
  65.     else
  66.     ary = stack;
  67.     orig = s;
  68.     if (spat->spat_flags & SPAT_SKIPWHITE) {
  69.     while (isSPACE(*s))
  70.         s++;
  71.     }
  72.     if (!limit)
  73.     limit = maxiters + 2;
  74.     if (strEQ("\\s+",spat->spat_regexp->precomp)) {
  75.     while (--limit) {
  76.         /*SUPPRESS 530*/
  77.         for (m = s; m < strend && !isSPACE(*m); m++) ;
  78.         if (m >= strend)
  79.         break;
  80.         dstr = Str_new(30,m-s);
  81.         str_nset(dstr,s,m-s);
  82.         if (!realarray)
  83.         str_2mortal(dstr);
  84.         (void)astore(ary, ++sp, dstr);
  85.         /*SUPPRESS 530*/
  86.         for (s = m + 1; s < strend && isSPACE(*s); s++) ;
  87.     }
  88.     }
  89.     else if (strEQ("^",spat->spat_regexp->precomp)) {
  90.     while (--limit) {
  91.         /*SUPPRESS 530*/
  92.         for (m = s; m < strend && *m != '\n'; m++) ;
  93.         m++;
  94.         if (m >= strend)
  95.         break;
  96.         dstr = Str_new(30,m-s);
  97.         str_nset(dstr,s,m-s);
  98.         if (!realarray)
  99.         str_2mortal(dstr);
  100.         (void)astore(ary, ++sp, dstr);
  101.         s = m;
  102.     }
  103.     }
  104.     else if (spat->spat_short) {
  105.     i = spat->spat_short->str_cur;
  106.     if (i == 1) {
  107.         int fold = (spat->spat_flags & SPAT_FOLD);
  108.  
  109.         i = *spat->spat_short->str_ptr;
  110.         if (fold && isUPPER(i))
  111.         i = tolower(i);
  112.         while (--limit) {
  113.         if (fold) {
  114.             for ( m = s;
  115.               m < strend && *m != i &&
  116.                 (!isUPPER(*m) || tolower(*m) != i);
  117.               m++)            /*SUPPRESS 530*/
  118.             ;
  119.         }
  120.         else                /*SUPPRESS 530*/
  121.             for (m = s; m < strend && *m != i; m++) ;
  122.         if (m >= strend)
  123.             break;
  124.         dstr = Str_new(30,m-s);
  125.         str_nset(dstr,s,m-s);
  126.         if (!realarray)
  127.             str_2mortal(dstr);
  128.         (void)astore(ary, ++sp, dstr);
  129.         s = m + 1;
  130.         }
  131.     }
  132.     else {
  133. #ifndef lint
  134.         while (s < strend && --limit &&
  135.           (m=fbminstr((unsigned char*)s, (unsigned char*)strend,
  136.             spat->spat_short)) )
  137. #endif
  138.         {
  139.         dstr = Str_new(31,m-s);
  140.         str_nset(dstr,s,m-s);
  141.         if (!realarray)
  142.             str_2mortal(dstr);
  143.         (void)astore(ary, ++sp, dstr);
  144.         s = m + i;
  145.         }
  146.     }
  147.     }
  148.     else {
  149.     maxiters += (strend - s) * spat->spat_regexp->nparens;
  150.     while (s < strend && --limit &&
  151.         regexec(spat->spat_regexp, s, strend, orig, 1, Nullstr, TRUE) ) {
  152.         if (spat->spat_regexp->subbase
  153.           && spat->spat_regexp->subbase != orig) {
  154.         m = s;
  155.         s = orig;
  156.         orig = spat->spat_regexp->subbase;
  157.         s = orig + (m - s);
  158.         strend = s + (strend - m);
  159.         }
  160.         m = spat->spat_regexp->startp[0];
  161.         dstr = Str_new(32,m-s);
  162.         str_nset(dstr,s,m-s);
  163.         if (!realarray)
  164.         str_2mortal(dstr);
  165.         (void)astore(ary, ++sp, dstr);
  166.         if (spat->spat_regexp->nparens) {
  167.         for (i = 1; i <= spat->spat_regexp->nparens; i++) {
  168.             s = spat->spat_regexp->startp[i];
  169.             m = spat->spat_regexp->endp[i];
  170.             dstr = Str_new(33,m-s);
  171.             str_nset(dstr,s,m-s);
  172.             if (!realarray)
  173.             str_2mortal(dstr);
  174.             (void)astore(ary, ++sp, dstr);
  175.         }
  176.         }
  177.         s = spat->spat_regexp->endp[0];
  178.     }
  179.     }
  180.     if (realarray)
  181.     iters = sp + 1;
  182.     else
  183.     iters = sp - arglast[0];
  184.     if (iters > maxiters)
  185.     fatal("Split loop");
  186.     if (s < strend || origlimit) {    /* keep field after final delim? */
  187.     dstr = Str_new(34,strend-s);
  188.     str_nset(dstr,s,strend-s);
  189.     if (!realarray)
  190.         str_2mortal(dstr);
  191.     (void)astore(ary, ++sp, dstr);
  192.     iters++;
  193.     }
  194.     else {
  195. #ifndef I286x
  196.     while (iters > 0 && ary->ary_array[sp]->str_cur == 0)
  197.         iters--,sp--;
  198. #else
  199.     char *zaps;
  200.     int   zapb;
  201.  
  202.     if (iters > 0) {
  203.         zaps = str_get(afetch(ary,sp,FALSE));
  204.         zapb = (int) *zaps;
  205.     }
  206.     
  207.     while (iters > 0 && (!zapb)) {
  208.         iters--,sp--;
  209.         if (iters > 0) {
  210.         zaps = str_get(afetch(ary,iters-1,FALSE));
  211.         zapb = (int) *zaps;
  212.         }
  213.     }
  214. #endif
  215.     }
  216.     if (realarray) {
  217.     ary->ary_fill = sp;
  218.     if (gimme == G_ARRAY) {
  219.         sp++;
  220.         astore(stack, arglast[0] + 1 + sp, Nullstr);
  221.         Copy(ary->ary_array, stack->ary_array + arglast[0] + 1, sp, STR*);
  222.         return arglast[0] + sp;
  223.     }
  224.     }
  225.     else {
  226.     if (gimme == G_ARRAY)
  227.         return sp;
  228.     }
  229.     sp = arglast[0] + 1;
  230.     str_numset(TARG,(double)iters);
  231.     STABSET(TARG);
  232.     st[sp] = TARG;
  233.     return sp;
  234. }
  235.  
  236.